﻿// ----------------------------------------------------------------------------
//  Copyright (C) 成都联宇创新科技有限公司 版权所有。 
//      
//  文件名：WcfHostedService.cs
//  文件功能描述：
//  创建标识：骆智慧 2016/03/03 00:00
//     
//  修改标识：骆智慧  2016/03/10/06:40
//  修改描述：
//  ----------------------------------------------------------------------------

#region 导入名称空间

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ServiceModel;
using System.Text;
using Common.Logging;
using LightWork.DynamicProxy.Internal;

#endregion

namespace LightWork.Services
{
    /// <summary>
    /// WCF批量宿主服务
    /// </summary>
    [Serializable]
    public class WcfHostService : Collection<ServiceHost>, IHostedService
    {
        private readonly ILog _log = LogManager.GetLogger<WcfHostService>();

        public WcfHostService()
        {
            ServiceName = GetType().Name;
        }

        public List<string> ServiceTypes { get; set; }

        public bool Continue()
        {
            return Start();
        }

        public void Dispose()
        {
            foreach (IDisposable disposable in this)
                disposable.Dispose();
        }

        public void Initialize()
        {
            try
            {
                StartIndex = 0;
                StopIndex = 1;
                ServiceName = "WCF批量宿主服务";
                CurrentState = CustomerServiceState.Init;
                if (null == ServiceTypes) return;

                foreach (var serviceType in ServiceTypes)
                {
                    var type = Type.GetType(serviceType, true);
                    Add(new ServiceHost(type));
                }
            }
            catch (Exception exception)
            {
                CurrentState = CustomerServiceState.Stoped;
                _log.Error(exception);
            }
        }

        public bool Pause()
        {
            return Stop();
        }

        public bool Start()
        {
            try
            {
                CurrentState = CustomerServiceState.Started;
                Open();
                return true;
            }
            catch (Exception exception)
            {
                CurrentState = CustomerServiceState.Starting;
                _log.Error(exception);
                return false;
            }
        }

        public bool Stop()
        {
            CurrentState = CustomerServiceState.Stoped;
            this.ForEach(host =>
            {
                switch (host.State)
                {
                    case CommunicationState.Created:
                    case CommunicationState.Opening:
                    case CommunicationState.Opened:
                    case CommunicationState.Faulted:
                        host.Abort();
                        return;

                    case CommunicationState.Closed:
                        return;
                }
                host.Close();
            });
            return true;
        }

        public CustomerServiceState CurrentState { get; set; }

        public string ServiceName { get; set; }

        public int StartIndex { get; set; }

        public int StopIndex { get; set; }

        private void HostOpenedHandle(object sender, EventArgs args)
        {
            var builder = new StringBuilder("\n");
            var openedHost = sender as ServiceHost;
            if (openedHost != null)
            {
                foreach (var endpoint in openedHost.Description.Endpoints)
                {
                    builder.AppendLine("服务协定:" + endpoint.Contract.ContractType);
                    builder.AppendLine("监听地址:" + endpoint.ListenUri);
                }
                builder.AppendLine("WCF 服务:" + openedHost.Description.ServiceType + " 启动成功");
            }
            _log.Info(builder.ToString());
        }

        private void HostClosedHandle(object sender, EventArgs args)
        {
            var theHost = sender as ServiceHost;
            if (theHost != null)
                _log.InfoFormat("WCF 服务 {0} 关闭成功……", theHost.Description.ServiceType);
        }

        private void Open()
        {
            foreach (var host in this)
                try
                {
                    if (host.State == CommunicationState.Opened) continue;
                    host.Opened += HostOpenedHandle;
                    host.Closed += HostClosedHandle;
                    host.Open();
                }
                catch (Exception exception)
                {
                    _log.ErrorFormat("WCF 服务{0}启动失败：{1}\r\n\r\n", host.Description.ServiceType, exception.Message);
                    throw;
                }
        }

        public override string ToString()
        {
            return string.Format("{0}:host {1} WCF服务", ServiceName, Count);
        }
    }
}